<template>
  <div v-if="total" class="xtx-pagination">

    <!-- 写两个a标签, 这样做的目的是为了, 既保持鼠标不可点击的样式, 点击时也不会触发事件 -->

    <!-- 当前页码为1, 上一页按钮处于禁用状态 -->
    <a v-if="myCurPage > 1"
       href="javascript:;"
       @click="changePage(myCurPage -1)">上一页</a>
    <a v-else class="disabled" href="javascript:;">上一页</a>
    <!-- 第一个按钮页码大于1, 显示 ... -->
    <span v-show="pager.start > 1">...</span>

    <a v-for="item in pager.btnArr"
       :key="item"
       :class="{active: item === myCurPage}"
       href="javascript:;"
       @click="changePage(item)">{{ item }}</a>


    <!-- 最后一个按钮页码小于总页数, 显示 ... -->
    <span v-show="pager.end < pager.pageCount">...</span>

    <!-- 当前页码大于总页数, 下一页按钮处于禁用状态 -->
    <a v-if="myCurPage < pager.pageCount"
       href="javascript:;"
       @click="changePage(myCurPage + 1)">下一页</a>
    <a v-else class="disabled" href="javascript:;">下一页</a>
  </div>
</template>

<script>
import { computed, ref, watch } from 'vue'

export default {
  name: 'XtxPagination',
  props: {
    count: {
      type: Number,
      default: 5
    },
    total: {
      type: Number,
      // 这个总数是必填的, 不需要设置默认值
      require: true
    },
    pageSize: {
      type: Number,
      default: 10
    },
    curPage: {
      type: Number,
      default: 1
    }
  },
  setup(props, { emit }) {
    // 需要数据:
    // 1.约定按钮的个数 5 个
    const myCount = ref(props.count)
    // 2.当前页码
    const myCurPage = ref(props.curPage)
    // 3.总页数 = 总条数 / 每页条数 向上取整 --> Note:   Math.ceil() === 向上取整
    const myTotal = ref(props.total)
    const myPageSize = ref(props.pageSize)

    // 其他数据 (总页数, 起始按钮, 结束按钮, 按钮数组) 依赖上面数据得到
    const pager = computed(() => {
      const myCurPageVal = myCurPage.value
      const countVal = myCount.value
      // 总页数
      const pageCount = Math.ceil(myTotal.value / myPageSize.value)
      // [ 3 ] [ 4 ] [-5-] [ 6 ] [ 7 ]
      // count按钮个数 和 myCurPage当前页码 --> 起始按钮, 结束按钮, 按钮数组

      // 1.理想情况下        // 注意JS的数值结构 let a = 5; a / 2 === 2.5
      const offset = Math.floor(countVal / 2)
      let start = myCurPageVal - offset
      // let end = myCurPageVal + offset
      let end = start + countVal - 1

      // 2.如果起始页码小于1, 需要特殊处理
      if (start < 1) {
        start = 1
        // 特殊情况: 约定按钮5个, 但是传进来的总页码只有4个
        end = (start + countVal - 1) > pageCount ? pageCount : (start + countVal - 1)
      }
      // 3.如果结束页码大于总页码, 需要特殊处理
      if (end > pageCount) {
        end = pageCount
        start = (end - countVal + 1) < 1 ? 1 : (end - countVal + 1)
      }

      const btnArr = []
      for (let i = start; i <= end; i++) {
        btnArr.push(i)
      }

      // 提供计算属性数据
      // console.log(btnArr)
      return {
        pageCount,
        start,
        end,
        btnArr
      }
    })

    // 切换分页函数
    const changePage = (newPage) => {
      myCurPage.value = newPage

      // 通知父组件
      emit('current-change', newPage)
    }

    // 监听props的变化, 更新组件内部数据, 为什么要使用监听其方式
    watch(props, () => {
      myCount.value = props.count
      myCurPage.value = props.curPage
      myTotal.value = props.total
      myPageSize.value = props.pageSize
    }, { immediate: true })

    return {
      myCount,
      myCurPage,
      myTotal,
      myPageSize,
      pager,
      changePage
    }
  }
}
</script>

<style lang="less" scoped>

.xtx-pagination {
  //background-color: #fff;
  padding: 30px;
  display: flex;
  justify-content: center;

  //text-align: center;

  > a {
    padding: 5px 10px;
    display: inline-block;
    border: 1px solid #e4e4e4;
    border-radius: 4px;
    margin-right: 10px;

    // 注意 hover 与 active 样式是有先后顺序的, 当hover到active按钮下
    // 由于 hover在 active的上面, 所有hover的color属性会被active的color所覆盖!!!
    &:hover {
      color: @xtxColor;
    }

    &.active {
      background: @xtxColor;
      color: #fff;
      border-color: @xtxColor;
    }


    &.disabled {
      opacity: 0.4;
      // 鼠标不可点击时的显示状态
      cursor: not-allowed;
      // 跟 pointer-events 同时使用会影响cursor的形状，比如“pointer-events:none;cursor:not-allowed;"后,
      // cursor:not-allowed 的鼠标形状不会改变为上图的鼠标样式，而只是变成了默认的鼠标箭头样式了。
      // pointer-events: none;
      &:hover {
        color: #333
      }
    }
  }

  > span {
    //position: relative;
    //top: -3px;
    margin-right: 10px;
  }
}
</style>
